package com.gitee.wsl.net.ssdp.description.model.xml

import com.gitee.wsl.logger.Logger
import com.gitee.wsl.logger.info
import com.gitee.wsl.net.ssdp.description.xml.XmlElement
import kotlin.properties.Delegates

/**
 * Defines bounds for legal numeric values; defines resolution for numeric values. Defined only for numeric data types
 * (i.e. integers and floats). At most one of the <allowedValueRange> or <allowedValueList> elements are allowed to be
 * specified. For a state variable using an extended data type via the type attribute and containing complex data, the
 * <allowedValueRange> element shall not be present
 * @param minimum - Inclusive lower bound. Defined by a UPnP Forum working committee or delegated to UPnP vendor. Single
 *                  numeric value. The value of the <minimum> element shall be less than the value of the <maximum>
 *                  element. If a working committee has assigned an explicit value for this element, then vendors shall
 *                  use that value. Otherwise, vendors shall choose their own value, but always within the allowed range
 *                  for the data type of this state variable. If the working committee defines an allowed range for this
 *                  state variable, then the value shall be within that allowed range as defined by the <step> value
 * @param maximum - Inclusive upper bound. Defined by a UPnP Forum working committee or delegated to UPnP vendor.
 *                  Single numeric value. The value of the <maximum> element shall be greater than the value of the
 *                  <minimum> element. If a working committee has assigned an explicit value for this element, then
 *                  vendors shall use that value. Otherwise, vendors shall choose their own value, but always within
 *                  the allowed range for the data type of this state variable. If the working committee defines an
 *                  allowed range for this
 * @param step    - Defines the set of allowed values permitted for the state variable between the <minimum> and
 *                  <maximum>. The value of the <step> element divides the inclusive range from <minimum> value to
 *                  <maximum> value into an integral number of equal parts. Additionally,
 *                  <maximum> value = <minimum> value + n * <step> value, where n is a positive integer.
 *                  Defined by a UPnP Forum working committee or delegated to UPnP vendor.
 *                  If a working committee has assigned an explicit value for this element, then vendors shall use that
 *                  value. Otherwise, vendors are allowed to choose their own value. When the <step> element is omitted
 *                  and the data type of the state variable is an integer, the default value of step is 1; otherwise,
 *                  when step is omitted, the state variable are allowed to be set to any value within the inclusive
 *                  range of <minimum> value to <maximum> value. Single numeric value.
 *                  Note that one should be carefull when dealing with floating point values so that conversions and/or
 *                  rounding errors do not cause inaccurate comparison operations.
 */
data class ValueRange(
    val minimum: String,
    val maximum: String,
    val step: String?
){
    companion object {
        fun fromXml(xml: XmlElement): ValueRange {
            var minimumS by Delegates.notNull<String>()
            var maximumS by Delegates.notNull<String>()
            var stepS: String? = null

            xml.children?.forEach {
                when(it.tag){
                    "minimum" -> minimumS = it.get()
                    "maximum" -> maximumS = it.get()
                    "step" -> stepS = it.getOrNull<String>()
                    else -> Logger.info("Unexpected tag ${it.tag}")
                }
            }
            return ValueRange(minimumS, maximumS, stepS)
        }
    }
}
